<?php
/**
 * $Id: tag.php 8 2009-01-28 07:54:19Z gpo_shrey $
 * 
 * This file can not be redistributed to anyone without the permission of Giga Promoters
 * Copyright 2005 - 2008, Giga Promoters
 * 						  608 Aggarwal Cyber Plaza
 *						  Netaji Subhash Place, Delhi - 110034
 *						  www.gigapromoters.com
 * 
 *
 * @version 			$Rev: 8 $
 * @lastModifiedBy		$LastChangedBy: gpo_shrey $
 * @lastChanged			$Date: 2009-01-28 13:24:19 +0530 (Wed, 28 Jan 2009) $
 * @copyright 			Giga Promoters (www.gigapromoters.com)
 * 
 */

/**
 * Tag Model. Need advanced functions in near future.
 *
 */
class Language extends AppModel
{
    var $name = 'Language';
	Const ACTIVE = 1;
	Const INACTIVE  =0;
	var $defaultCacheKey = "default_langugae";
	function afterSave($created)
	{
		if(isset($this->data[$this->alias]['status']) && $this->data[$this->alias]['status'] == self::ACTIVE)
		{
			Cache::set(array('path'=>CACHE));
			Cache::delete($this->defaultCacheKey);
			//$this->setLanguageConfiguration(false);
		}
    GigaCache::set(array("path"=>"+1 day","path"=>CACHE));
    GigaCache::delete("languages_list");
		parent::afterSave($created);
	}
	public static function getLanguages($complete = false)
	{
		uses('I18n');
		$langugaes = array();
		$I18nInstance = I18n::getInstance();
		$invlaidLanguages = cr('Langugae.invlaidLanguages');
		if(!is_array($invlaidLanguages))
		{
			$invlaidLanguages = array();
 		}
		foreach($I18nInstance->l10n->__l10nCatalog as $code => $info)
		{
			if(strpos($code,'-')!==false || in_array($code,$invlaidLanguages))
			{
				continue;				
			}
			if($complete == true)
			{
				$langugaes[$code] =  $info;
			}else
			{
				$langugaes[$code] = $info['language'];
			}
		}
		return $langugaes;
	}
	function getLanguage($code)
	{
		$langugaes = self::getLanguages(true);
		return $langugaes[$code];
	}
	function getLocaleName($code)
	{
		$langugaes = self::getLanguages(true);
		$locale = null;
		if(isset($langugaes[$code]))
		{
			$locale = $langugaes[$code]['locale'];
		}
		return $locale;
	}
		
	function addLocaleFile($code,$content)
	{
		$filePath = $this->getPoFilePath($code);
		$dirPath = dirname($filePath).DS;
		if(!file_exists($filePath))
		{
			uses('folder');
			$obj = new Folder();
			$obj->create($dirPath,0777);
		}else
		{
			//take a bakup of old
			$backupFile = $dirPath.'default_'.date('Y_m_d_H_i').'.po';
			copy($filePath,$backupFile) ;
		}
		return file_put_contents($filePath,$content);
	}
	protected function getPoFilePath($code)
	{
		$locale = self::getLocaleName($code);
		$fileName = 'default.po'; 
		$localeName = self::getLocaleName($code);
		$dirPath = APP.'locale'.DS.$localeName.DS.'LC_MESSAGES'.DS;
		$filePath = $dirPath.$fileName;
		return $filePath;
	}
	function setLanguageConfiguration($cache= true)
	{
		Cache::set(array('path'=>CACHE,'duration'=>'+999 days'));
		$defaultLanguage = Cache::read($this->defaultCacheKey);
		if($defaultLanguage === false || $cache==false)
		{
			$rand = rand();
			$defaultLanguage = $this->field('code',array('is_default'=>1,"$rand = $rand")); 
			if($defaultLanguage == false)
			{
				$defaultLanguage = null;
			}
			//if no return set current language.
			if($defaultLanguage == null)
			{
				$defaultLanguage = cr('Config.language');
				$defaultLanguage = array_shift(explode('-',$defaultLanguage));
				
			}
			Cache::write($this->defaultCacheKey,$defaultLanguage);
		}
		$language = $defaultLanguage;
		$userLanguage = cr("Language.userLanguage");
		if($userLanguage)
		{
			$language = $userLanguage;
		}
		if($language)
		{
			Configure::write('Config.language',$language);
			$language = self::getLanguage($language);
			$encoding = $language['charset'];
			//Configure::write('App.encoding',$encoding);
		}		
	}
	
	function delPersistentCacheFile($code)
	{
		$localName = self::getLocaleName($code);
		$file = TMP . 'cache'.DS.'persistent'.DS.'cake_core_default_'.$localName;
		if(file_exists($file) != false)
		{
			@unlink($file);
		}
	}
	
	function getTranslationsStrings($code)
	{
		$poFile = $this->getPoFilePath($code);
		$defaultStrings = $this->extractStrings($this->getDefaultPoFile());
		$translations = array();
		if(file_exists($poFile))
		{
			$translations = $this->extractStrings($poFile);
			unset($translations[""]);
		}
		$translations = am($defaultStrings,$translations);
		return $translations;
	}
	
	protected function extractStrings($file)
	{
		$file = fopen($file,'r');
		$type = 0;
		$translations = array();
		$translationKey = "";
		$plural = 0;
		$header = "";
		do {
			$line = trim(fgets($file, 1024));
			if ($line == "" || $line[0] == "#") {
				continue;
			}
			if (preg_match("/msgid[[:space:]]+\"(.+)\"$/i", $line, $regs)) {
				$type = 1;
				$translationKey = stripcslashes($regs[1]);
			} elseif (preg_match("/msgid[[:space:]]+\"\"$/i", $line, $regs)) {
				$type = 2;
				$translationKey = "";
			} elseif (preg_match("/^\"(.*)\"$/i", $line, $regs) && ($type == 1 || $type == 2 || $type == 3)) {
				$type = 3;
				$translationKey .= stripcslashes($regs[1]);
			} elseif (preg_match("/msgstr[[:space:]]+\"(.+)\"$/i", $line, $regs) && ($type == 1 || $type == 3) && $translationKey) {
				$translations[$translationKey] = stripcslashes($regs[1]);
				$type = 4;
			} elseif (preg_match("/msgstr[[:space:]]+\"\"$/i", $line, $regs) && ($type == 1 || $type == 3) && $translationKey) {
				$type = 4;
				$translations[$translationKey] = "";
			} elseif (preg_match("/^\"(.*)\"$/i", $line, $regs) && $type == 4 && $translationKey) {
				$translations[$translationKey] .= stripcslashes($regs[1]);
			} elseif (preg_match("/msgid_plural[[:space:]]+\".*\"$/i", $line, $regs)) {
				$type = 6;
			} elseif (preg_match("/^\"(.*)\"$/i", $line, $regs) && $type == 6 && $translationKey) {
				$type = 6;
			} elseif (preg_match("/msgstr\[(\d+)\][[:space:]]+\"(.+)\"$/i", $line, $regs) && ($type == 6 || $type == 7) && $translationKey) {
				$plural = $regs[1];
				$translations[$translationKey][$plural] = stripcslashes($regs[2]);
				$type = 7;
			} elseif (preg_match("/msgstr\[(\d+)\][[:space:]]+\"\"$/i", $line, $regs) && ($type == 6 || $type == 7) && $translationKey) {
				$plural = $regs[1];
				$translations[$translationKey][$plural] = "";
				$type = 7;
			} elseif (preg_match("/^\"(.*)\"$/i", $line, $regs) && $type == 7 && $translationKey) {
				$translations[$translationKey][$plural] .= stripcslashes($regs[1]);
			} elseif (preg_match("/msgstr[[:space:]]+\"(.+)\"$/i", $line, $regs) && $type == 2 && !$translationKey) {
				$header .= stripcslashes($regs[1]);
				$type = 5;
			} elseif (preg_match("/msgstr[[:space:]]+\"\"$/i", $line, $regs) && !$translationKey) {
				$header = "";
				$type = 5;
			} elseif (preg_match("/^\"(.*)\"$/i", $line, $regs) && $type == 5) {
				$header .= stripcslashes($regs[1]);
			} else {
				unset($translations[$translationKey]);
				$type = 0;
				$translationKey = "";
				$plural = 0;
			}
		}
		while (!feof($file));
		fclose($file);
		$merge[""] = $header;
		return array_merge($merge ,$translations);
	}
	
	function getDefaultPoFile()
	{
		//look for file in in locale folder first then in english folder.
		$localeFile = APP.'locale'.DS.'default.po';
		if(file_exists($localeFile))
		{
			return $localeFile;
		}
		$localeFile = APP.'locale'.DS.'eng'.DS.'LC_MESSAGES'.DS.'default.po';
		return $localeFile;
	}
	
	function makePoFile($code,$tranlations)
	{
		$output  = "# Web translation\n";
		$output .= "#\n";
		$output .= "#\"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\\n\"\n";
		$output .= "#, fuzzy\n";
		$output .= "msgid \"\"\n";
		$output .= "msgstr \"\"\n";
		$output .= "\"POT-Creation-Date: " . date("Y-m-d H:iO") . "\\n\"\n";
		$output .= "\"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\\n\"\n";
		$output .= "\"MIME-Version: 1.0\\n\"\n";
		$output .= "\"Content-Type: text/plain; charset=utf-8\\n\"\n";
		$output .= "\"Content-Transfer-Encoding: 8bit\\n\"\n";
		$output .= "\n\n"; 
		$oldTranslations = $this->getTranslationsStrings($code);
		$tranlationArray = array();
		foreach ($tranlations as $key => $translation)
		{
			if(strlen($translation['msgid']))
			{
				$tranlationArray[$translation['msgid']] = $translation['msgstr'];
			}
		}
		$tranlations = array();
		$tranlations = am($oldTranslations,$tranlationArray);
		foreach($tranlations as $translateKey => $translation)
		{
			if(strlen($translateKey) == 0)
			{
				continue;
			}
			$msgId = $this->formatPoString($translateKey);
			$msgStr = $this->formatPoString($translation);
			$output .= "msgid \"$msgId\"\n";
			$output .= "msgstr \"$msgStr\"\n";
		}
		$return =  $this->addLocaleFile($code, $output);
		Cache::set(array('path'=>CACHE));
		Cache::delete($this->defaultCacheKey);
		$this->delPersistentCacheFile($code);
		return $return;
	}
	
	private function formatPoString($string)
	{
		$quote = substr($string, 0, 1);
		if ($quote == '"') {
			$string = stripcslashes($string);
		} else {
			$string = strtr($string, array("\\'" => "'", "\\\\" => "\\"));
		}
		$string = str_replace("\r\n", "\n", $string);
		return addcslashes($string, "\0..\37\\\"");
	}
	
	/**
	 * Get id of languae code in table
	 * if code not present then insserts it.
	 */
	function getLanguageId($code)
	{
		$id = $this->field('id',array("code"=>$code));
		if(!$id)
		{
			$this->create();
			$this->save(array($this->alias => array("code"=>$code)));
			$id = $this->id;
		}
		return $id;
	}
	
	function getActiveLangaugeLists($refresh = false)
	{
		GigaCache::set(array("path"=>"+1 day","path"=>CACHE));
		$cachKey = "languages_list";
		$languages = GigaCache::read($cachKey);
		if($languages === false || $refresh)
		{
			$_this = cri("Language");
			$languages = $_this->find("list",array("conditions"=>array("status"=>self::ACTIVE),'fields'=>array("code")));
			$languageList = self::getLanguages();
			if($languages)
			{
				$languages = array_intersect_key($languageList,array_combine($languages,$languages));
			}else{
				$languages = array();
			}
			GigaCache::set(array("duration"=>"+1 day"));
			GigaCache::write($cachKey,$languages);
		}
		return $languages;
	}
	
	function isActiveLanguage($code)
	{
		/*
		if(cr('Config.language') == $code)
		{
			return true;
		}
		*/
		return $this->hasAny(array($this->alias.".code" => $code, $this->alias.".status" => self::ACTIVE));
	}
}

?>